home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / lib / amiga / cstack.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  3KB  |  130 lines

  1.  
  2. /*
  3.  *  CSTACK.C
  4.  *
  5.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  6.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  7.  *    DICE-LICENSE.TXT.
  8.  *
  9.  *  Dynamic Stack Allocation.  If this library module is brought it
  10.  *  then dynamic stacking is in effect.
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <exec/types.h>
  17. #include <exec/tasks.h>
  18. #include <clib/exec_protos.h>
  19.  
  20. extern long _cur_fudge;
  21. extern long _cur_chunk;
  22. extern char *_stk_base;
  23. extern long _stack_fudge;
  24. extern long _stack_chunk;
  25.  
  26. extern __stkargs void _stk_free(void);
  27. extern __stkargs void _stack_panic(const char *);
  28.  
  29. /*
  30.  *  _CStackAlloc(&ctlframe)
  31.  */
  32.  
  33. __stkargs
  34. void *
  35. _CStackAlloc(psf, a5space)
  36. long *psf;
  37. long a5space;
  38. {
  39.     char *new;
  40.     char *tmp;
  41.     long bytes = _stack_chunk;    // minimum stack chunking size
  42.     long copybytes = psf[1] +    // arguments passed by original caller
  43.              4 +    // return vector by original caller
  44.              psf[0] +    // registers saved by callee
  45.              4;     // fp pushed by callee
  46.     if (bytes < copybytes + a5space + 256)
  47.     bytes = copybytes + a5space + 256;
  48.  
  49.     //printf("bytes=%d copybytes=%d a5space=%d\n", bytes, copybytes, a5space);
  50.  
  51.     /*
  52.      *    allocate new stack
  53.      */
  54.  
  55.     while ((new = malloc(bytes + _stack_fudge)) == NULL)
  56.     stack_abort();
  57.  
  58.     //printf("newstack %08lx-%08lx\n", new, bytes + _stack_fudge);
  59.  
  60.     /*
  61.      *    alloc space off the top of the new space to copy the original
  62.      *    procedural arguments, return vector, callee's saved registers,
  63.      *    and A5.
  64.      */
  65.  
  66.     tmp = new + bytes + _stack_fudge;
  67.     tmp -= copybytes;    // caller args, rts vec, callee regs, callee fp
  68.     movmem((char *)psf + 8, tmp, copybytes);
  69.  
  70.     /*
  71.      *    setup the return vector on the new stack to point to stk_free,
  72.      *    setup the return FP to point to the real return FP on the original
  73.      *    stack.    The real return FP on the original stack is moved to the
  74.      *    top of the saved registers on the original stack.
  75.      */
  76.  
  77.     extern void main();
  78.     //printf("returnvector %08lx main %08lx (%08lx)\n",
  79.     //      *(long *)(tmp + 4 + psf[0]),
  80.     //      main,
  81.     //      *(long *)(tmp + 4 + psf[0]) - (long)main,
  82.     //);
  83.  
  84.     *(long *)(tmp + 4 + psf[0]) = (long)_stk_free;
  85.     *(long *)(tmp) = (long)((char *)psf + 8 + psf[0]);
  86.     *(long *)((char *)psf + 8 + psf[0]) = psf[2];
  87.  
  88.     /*
  89.      *    save old stack information
  90.      */
  91.  
  92.     ((long *)new)[0] = 0;    // currently unused field.
  93.     ((long *)new)[1] = (long)_stk_base;
  94.     ((long *)new)[2] = _cur_fudge;
  95.     ((long *)new)[3] = bytes;
  96.  
  97.     _cur_fudge = _stack_fudge;
  98.     _cur_chunk = _stack_chunk;
  99.     _stk_base = new + _cur_fudge;
  100.     //printf("return %08lx\n", tmp);
  101.     return(tmp);
  102. }
  103.  
  104. /*
  105.  *  CStackFree is called to free up the current stack frame.  We have
  106.  *  already been moved back to the old stack.
  107.  */
  108.  
  109. __stkargs
  110. void
  111. _CStackFree()
  112. {
  113.     char *old = _stk_base - _cur_fudge;
  114.     void x;
  115.  
  116.     if ((char *)&x >= old && (char *)&x < old + _cur_fudge + _cur_chunk)
  117.     _stack_panic("badstkptr");
  118.     if (_cur_chunk == 0)
  119.     _stack_panic("chksz0");
  120.  
  121.     //printf("restore frame %08lx\n", ((long *)old)[1]);
  122.  
  123.     _stk_base = (char *)((long *)old)[1];
  124.     _cur_fudge    = ((long *)old)[2];
  125.     _cur_chunk    = ((long *)old)[3];
  126.  
  127.     free(old);
  128. }
  129.  
  130.